package com.quanquan.user.service;

import DTO.Commercial.CommercialInfoDTO;
import DTO.PageDTO;
import DTO.store.StoreDTO;
import DTO.store.StoreInfoDTO;
import com.quanquan.user.configBeans.RabbitSender;
import com.quanquan.user.dto.IdDTO;
import com.quanquan.user.dto.SelfHelpIntegralDTO;
import com.quanquan.user.entity.*;
import com.quanquan.user.exception.ConsumptionQuotaException;
import com.quanquan.user.exception.SelfHelpIntegralException;
import com.quanquan.user.exception.UserException;
import com.quanquan.user.repository.*;
import com.quanquan.user.request.ConsumptionAmountRequestBody;
import com.quanquan.user.request.SelfHelpRequestBody;
import com.quanquan.user.service.weixin.Proxy;
import com.quanquan.user.service.weixin.template.TemplateRequest;
import commond.ImageOutPut;
import commond.IntegralOutPut;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.internal.Function;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import utils.DateUtils;
import utils.StringUtil;
import utils.StringUtils;
import utils.UUIDGenerator;

import javax.persistence.criteria.Predicate;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 功能描述:自助积分业务层
 *
 * @ClassName: SelfHelpIntegralService
 * @Author: xiaoqianh丶
 * @Date: 2019-04-12 09:57
 * @Version: V1.0
 */
@Service
public class SelfHelpIntegralService {

    private static final String CONSUMPTION_QUOTA_RULE = "consumptionQuotaRule";
    private static final String SALF = "零售";
    private static final String FOOD = "餐饮";
    private static final String HAPPY = "娱乐";
    private static final String CHECK_TIME = "2019-09-01";
    private static final String OTHER_CHECK_TIME = "2019-09-25";
    private static final String OTHER = "其它";
    private static final String SERVICES = "服务";
    private static final String COMMERCIAL = "commercial_";
    public static final String INTEGRAL = "integral";
    public static final String COUPON = "coupon";
    public static final String PARKING = "parking";
    public static final String ARTIFICIAL = "artificial";
    public static final String CHECK = "check";
    public static final String COMMERCIALSS = "e905cfe61c5a46f891d56cc463f4a359";
    private final ConsumptionQuotaService consumptionQuotaService;
    private final SelfHelpIntegralRepository selfHelpIntegralRepository;
    private final RabbitSender rabbitSender;
    private final RestTemplate restTemplate;
    private final UserService userService;
    private final RedisTemplate redisTemplate;
    private final UserLevelService userLevelService;
    private final IntegralRuleService integralRuleService;
    private final ConsumptionAmountService consumptionAmountService;

    private final StringRedisTemplate stringRedisTemplate;
    private final MarketingRulesRepository marketingRulesRepository;

    @Autowired
    private ScratchCardConfigurationRepository scratchCardConfigurationRepository;
    @Autowired
    private CommercialDoubleRepository commercialDoubleRepository;
    /**
     * reviewing, failpass ,successpass // 审核中 审核未通过 通过审核
     */


    private final static String SUCCESSPASS = "successpass";
    private final static String REVIEWING = "reviewing";

    private final static String FAILPASS = "failpass";//
    private final Proxy proxy;
    @Autowired
    private PosOrderRepository posOrderRepository;

    @Autowired
    public SelfHelpIntegralService(SelfHelpIntegralRepository selfHelpIntegralRepository, RabbitSender rabbitSender, RestTemplate restTemplate, UserService userService, RedisTemplate redisTemplate, UserLevelService userLevelService, IntegralRuleService integralRuleService, ConsumptionAmountService consumptionAmountService, Proxy proxy, ConsumptionQuotaService consumptionQuotaService, StringRedisTemplate stringRedisTemplate, MarketingRulesRepository marketingRulesRepository) {
        this.selfHelpIntegralRepository = selfHelpIntegralRepository;
        this.rabbitSender = rabbitSender;
        this.restTemplate = restTemplate;
        this.userService = userService;
        this.redisTemplate = redisTemplate;
        this.userLevelService = userLevelService;
        this.integralRuleService = integralRuleService;
        this.consumptionAmountService = consumptionAmountService;
        this.proxy = proxy;
        this.consumptionQuotaService = consumptionQuotaService;
        this.stringRedisTemplate = stringRedisTemplate;
        this.marketingRulesRepository = marketingRulesRepository;
    }

    /**
     * 创建自助积分申请
     *
     * @param requestBody
     */
    public String createSelfHelpApplication(SelfHelpRequestBody requestBody) {


        saveSelfHelpIntegral(requestBody);
        return "拍照上传小票成功";


    }

    public boolean createSelfHelpApplicationAndAuto(SelfHelpRequestBody requestBody) throws SelfHelpIntegralException {
        //根据用户手机号查询用户
        User user = userService.findUserByPhone(requestBody.getPhone());

        if (user == null) {
            throw new SelfHelpIntegralException("用户信息错误");
        }
        Integer freeze = user.getFreeze();
        if (freeze != 0) {
            throw new SelfHelpIntegralException("该用户已被冻结");
        }
        SelfHelpIntegral selfHelpIntegral;
        String ticketNum = requestBody.getTicketNum();
        String consumeDay = requestBody.getConsumeDay();
        String storeId = requestBody.getStoreId();
        System.out.println("storeId.."+storeId);
        List<String> list = new ArrayList<>();
        list.add(storeId);
        //根据商户id查询业态
        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(list);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();

        String commercialId = null;
        if (storeDTOS.size() > 0) {
            StoreDTO storeDTO = storeDTOS.get(0);
            commercialId = storeDTO.getCommercialId();
        }
        Boolean result = false;
        // 刮刮卡宣传链接
        String url = null;
        List<SelfHelpIntegral> selfHelpIntegral5= selfHelpIntegralRepository.checkSelfHelpIntegral(ticketNum, consumeDay, storeId);
        SelfHelpIntegral selfHelpIntegral1 =null;
        if(selfHelpIntegral5.size()>0){
            selfHelpIntegral1 = selfHelpIntegral5.get(0);
        }
        if (selfHelpIntegral1 != null && (selfHelpIntegral1.getApplicationStatus()).equals(SelfHelpIntegral.Application.successpass)) {

            return false;
        } else if (selfHelpIntegral1 != null && !(selfHelpIntegral1.getApplicationStatus()).equals(SelfHelpIntegral.Application.successpass)) {
            selfHelpIntegral1.setApplicationStatus(SelfHelpIntegral.Application.successpass);
            selfHelpIntegralRepository.save(selfHelpIntegral1);
            selfHelpIntegral = selfHelpIntegral1;
        } else {
            SelfHelpIntegral selfHelpIntegral2 = new SelfHelpIntegral();
            //通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(requestBody, selfHelpIntegral2);
            selfHelpIntegral2.setId(UUIDGenerator.getUUID());
            selfHelpIntegral2.setRemove(0);
            selfHelpIntegral2.setCreateTime(DateUtils.currentDate());
            selfHelpIntegral2.setUserId(user.getId());
            selfHelpIntegral2.setApplicationStatus(SelfHelpIntegral.Application.successpass);
            selfHelpIntegral2.setAuditChannel(ARTIFICIAL);
            selfHelpIntegralRepository.save(selfHelpIntegral2);
            selfHelpIntegral = selfHelpIntegral2;

            //刮刮卡活动
            //判断时间是否是9月1号到30号
            List<ScratchCardConfiguration> all = scratchCardConfigurationRepository.findAll();
            ScratchCardConfiguration scratchCardConfiguration = all.get(0);
            Long scratchId = scratchCardConfiguration.getScratchId();
            url = scratchCardConfiguration.getUrl();
            Date startTime = DateUtils.parseStr2Date("yyyy-MM-dd", scratchCardConfiguration.getStartTime());
            Date endTime = DateUtils.parseStr2Date("yyyy-MM-dd", scratchCardConfiguration.getEndTime());
            Date nowDate = DateUtils.parseStr2Date("yyyy-MM-dd", consumeDay);

            if (nowDate.after(startTime) && nowDate.before(endTime)) {

                String money = requestBody.getMoney();
                //金额取整
                int i = integerNum(money);
                if (i >= 50) {
                    //发送队列，抽奖次数加1
                    addTimes(user.getId(), scratchId);
                    result = true;
                }
            }


            //绑定图片关系
            bandingImageShip(selfHelpIntegral.getId(), requestBody.getImageId());
            //生成消费记录
            ConsumptionAmountRequestBody consumptionAmountRequestBody = new ConsumptionAmountRequestBody();//通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(selfHelpIntegral, consumptionAmountRequestBody);
            //同步消费数据
            consumptionAmountRequestBody.setConsumeType("商场缴费");
            consumptionAmountService.createConsumptionAmount(consumptionAmountRequestBody);
        }


        if (systemReward(user, selfHelpIntegral, consumeDay, storeDTOS)) {

            TemplateRequest templateRequest = new TemplateRequest();
            templateRequest.setDetail("满赠活动");
            templateRequest.setOpenId(user.getWxOpenid());
            templateRequest.setIntegral(selfHelpIntegral.getReceivePoint());
            templateRequest.setReason("小票核销");
            templateRequest.setCreateTime(selfHelpIntegral.getCreateTime());
            Integer integral = Integer.parseInt(selfHelpIntegral.getReceivePoint());
            Integer sumIntegral = user.getIntegral() + integral;
            templateRequest.setSumIntegral(Integer.toString(sumIntegral));
            templateRequest.setMoney(selfHelpIntegral.getMoney());

            if (result && commercialId.equals(COMMERCIALSS)) {
                templateRequest.setRemark("☛☛☛金秋美食节，点我刮奖，来试试运气吧☚☚☚");
                templateRequest.setUrl(url);
            }
            //填充商户信息
            IdDTO idDTO = new IdDTO();
            List<String> foreignKeyIds = new LinkedList<>();
            foreignKeyIds.add(selfHelpIntegral.getStoreId());
            idDTO.setForeignKeyIds(foreignKeyIds);
            StoreInfoDTO storeInfoDTO1 = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
            List<StoreDTO> stores = storeInfoDTO1.getStoreDTOS();
            System.out.println(stores.get(0).getStoreName());
            templateRequest.setShopName(stores.get(0).getStoreName());
            proxy.sendIntegralSumTemplate(templateRequest);
            return true;
        }


        return false;
    }

    //判断积分是否要翻倍
    private boolean systemReward(User user, SelfHelpIntegral selfHelpIntegral, String consumeDay, List<StoreDTO> storeDTOS) {
        if (storeDTOS.size() > 0) {
            StoreDTO storeDTO = storeDTOS.get(0);
            String money = selfHelpIntegral.getMoney();
            //根据key值查询业态信息
            String commercialId = storeDTO.getCommercialId();
            int integralProportion = 1;
            try {
                String result = redisTemplate.opsForValue().get(COMMERCIAL + commercialId).toString();
                if (StringUtil.isNotEmpty(result)) {
                    integralProportion = Integer.parseInt(result);
                }
            } catch (Exception e) {
                //http 根据业态id查询业态信息
                CommercialInfoDTO commercialInfoDTO = getCommercialInfoDTO(commercialId);
                if (commercialInfoDTO != null) {
                    integralProportion = commercialInfoDTO.getPercent();
                }
            }

            //金额取整
            int i = integerNum(money);
            //会员翻倍，业态兑换比例，生日翻倍，时间段翻倍
            int firstNum = 0;
            if (i != 0) {
                //算出积分(业态兑换比例)
                firstNum = i / integralProportion;
            }
            //积分翻倍规则(会员等级翻倍 ，会员生日翻倍，时间段翻倍)
            firstNum = getFirstNum(user, selfHelpIntegral, consumeDay, firstNum, commercialId);

            //生日翻倍
            //时间段翻倍

            String integralPoint = String.valueOf(firstNum);

            sountIntegral(integralPoint, selfHelpIntegral, user.getId());
            selfHelpIntegral.setReceivePoint(integralPoint);
            selfHelpIntegralRepository.save(selfHelpIntegral);

            boolean type = false;

            Boolean consumptionQuota = false;
            //查询积分规则(先查缓存，没有缓存后查数据库)
            BoundHashOperations<String, String, Object> redisMarketingRule = redisTemplate.boundHashOps("marketingRules");
            if (redisMarketingRule.size() > 0) {

                consumptionQuota = (Boolean) redisMarketingRule.get("consumptionQuota");

            } else {
                List<MarketingRules> all = marketingRulesRepository.findAll();
                MarketingRules marketingRules = all.get(0);
                consumptionQuota = marketingRules.getConsumptionQuota();
            }
            //判断是否要开启满额 // TODO: 2019-06-10
            if (consumptionQuota) {
                //判断是否要满额有其他动作（暂且只有一个动作）
                Boolean aBoolean = stringRedisTemplate.hasKey(CONSUMPTION_QUOTA_RULE);
                if (!aBoolean) {
                    consumptionQuotaService.calculation();
                }
                String consumptionQuotaRule = stringRedisTemplate.opsForValue().get(CONSUMPTION_QUOTA_RULE);
                boolean contains = consumptionQuotaRule.contains(",");
                //将金额与规则比较，确定满足的是啥规则

                String consumptionQuota2 = null;
                if (contains) {
                    //先从缓存中取出规则,放入到map中
                    String[] split = consumptionQuotaRule.split(",");

                    for (int j = 0; j < split.length; j++) {
                        if (i >= Integer.parseInt(split[j])) {
                            consumptionQuota2 = split[j];
                            break;
                        }
                    }
                } else {
                    if(i>=Integer.valueOf(consumptionQuotaRule)){
                        consumptionQuota2 = consumptionQuotaRule;
                    }else{
                        return true;
                    }
                }
                //根据满额阀值查询满额规则
                try {
                    ConsumptionQuota consumptionQuota1 = consumptionQuotaService.findConsumptionQuota(consumptionQuota2);

                    //根据规则阀值查询满额规则
                    //根据规则类型确定是发送那个队列
                    String marketingType = consumptionQuota1.getMarketingType();
                    String marketingRule = consumptionQuota1.getMarketingRule();
                    //送积分
                    if (INTEGRAL.equals(marketingType)) {

                        sountIntegral(marketingRule, user.getId());
                    }
                    //送优惠券单张
                    if (COUPON.equals(marketingType)) {
                        List<String> couponIds = new ArrayList<>();
                        couponIds.add(marketingRule);
                        List<String> userIds = new ArrayList<>();
                        userIds.add(user.getId());
                        String coupomCountNum = "1";
                        //调用队列
                        sendCoupomMQ(couponIds, coupomCountNum, userIds);
                    }
                    //送停车券
                    if (PARKING.equals(marketingType)) {
                        List<String> couponIds = new ArrayList<>();
                        couponIds.add(marketingRule);
                        List<String> userIds = new ArrayList<>();
                        userIds.add(user.getId());
                        String coupomCountNum = "1";
                        //调用队列
                        sendCoupomMQ(couponIds, coupomCountNum, userIds);
                    }
                } catch (ConsumptionQuotaException e) {
                    e.printStackTrace();
                }
            }

            //判断消费时间
            return true;
        }
        return false;
    }

    //添加积分明细
    private void sountIntegral(String integralPoint, String userId) {
        IntegralOutPut integralOutPut = new IntegralOutPut();
        integralOutPut.setConsumeType("consumptionQuota");
        integralOutPut.setForeignKeyId(userId);
        integralOutPut.setIntegralPoint(integralPoint);
        integralOutPut.setUserId(userId);
        integralOutPut.setOrderNum(userId);
        integralOutPut.setSource("消费满额奖励");
        integralOutPut.setTradeAction(0);
        integralOutPut.setTradingContent("消费满额奖励");

        String exchange = "integral.exchange";
        String routingKey = "integral.registered";
        rabbitSender.sendMessageToMQ(integralOutPut, null, exchange, routingKey);
    }

    //发送优惠券
    private void sendCoupomMQ(List<String> coupomIds, String coupomNum, List<String> userIds) {
        Map<String, Object> properties = new HashMap<>();
        properties.put("userIds", userIds);
        properties.put("coupomIds", coupomIds);
        properties.put("coupomNum", coupomNum);

        String exchange = "coupon.exchange";
        String routingKey = "coupon.sendCoupon";

        rabbitSender.sendMessageToMQ("用户发券", properties, exchange, routingKey);
    }

    /**
     * 判断当前日期是星期几
     *
     * @param pTime 修要判断的时间
     * @return dayForWeek 判断结果
     * @Exception 发生异常
     */
    private int dayForWeek(String pTime) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(format.parse(pTime));
        int dayForWeek = 0;
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            dayForWeek = 7;
        } else {
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    private int getFirstNum(User user, SelfHelpIntegral selfHelpIntegral, String consumeDay, int firstNum, String commercialId) {
        String createTime = selfHelpIntegral.getCreateTime();
        //判断消费日期是否是周三
        int i = 0;
        try {
            i = dayForWeek(consumeDay);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //当日时间
        String subTime = createTime.substring(0, 10);
        boolean timeDouble;
        boolean memberBirthDayDouble;
        boolean memberLevelDouble;
        boolean storeCommercial;

        //查询积分规则(先查缓存，没有缓存后查数据库)
        BoundHashOperations<String, String, Boolean> redisIntegralRule = redisTemplate.boundHashOps("integralRule");
        if (redisIntegralRule.size() > 0) {
            timeDouble = redisIntegralRule.get("timeDouble");
            memberBirthDayDouble = redisIntegralRule.get("memberBirthDayDouble");
            memberLevelDouble = redisIntegralRule.get("memberLevelDouble");
            storeCommercial = redisIntegralRule.get("storeCommercial");

        } else {
            IntegralRule integralRule = integralRuleService.findIntegralRule();
            timeDouble = integralRule.getTimeDouble();
            memberBirthDayDouble = integralRule.getMemberBirthDayDouble();
            memberLevelDouble = integralRule.getMemberLevelDouble();
            storeCommercial = integralRule.getStoreCommercial();
        }

        if (memberLevelDouble) {
            //会员等级翻倍
            String userId = user.getId();
            int multiply = userLevelService.findUserLevel(userId);
            firstNum = firstNum * multiply;
        }
        if (memberBirthDayDouble) {
            if (StringUtil.isNotEmpty(user.getBirthday())) {
                String substring = subTime.substring(5, 10);
                String userBirthday = user.getBirthday();
                if (StringUtils.isNotEmpty(userBirthday)) {
                    String birthDay = user.getBirthday().substring(5, 10);
                    if (birthDay.equals(substring)) {
                        //查询生日翻倍的倍数
                        String birthDayDouble = redisTemplate.opsForValue().get("birthDayDouble").toString();
                        int doubleNum = Integer.parseInt(birthDayDouble);
                        firstNum = firstNum * doubleNum;
                    }
                }


            }
        }
        if (timeDouble) {

            //查询时间段
            String integralTimeDouble = redisTemplate.opsForValue().get("integralTimeDouble").toString();
            if (StringUtil.isNotEmpty(integralTimeDouble)) {
                String[] times = integralTimeDouble.split(",");
                String startTime = times[0];
                String endTime = times[1];
                //翻倍系数
                String timeDoubleNum = times[2];
                int DoubleNum = Integer.parseInt(timeDoubleNum);

                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(startTime, DateUtils.DATE));
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(endTime, DateUtils.DATE));
                //查看小票消费日期
                Date consumeDayTime = DateUtils.parseStr2Date("yyyy-MM-dd", consumeDay);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(consumeDayTime);
                calendar.add(Calendar.HOUR, 1);
                Date consumeDayTimes = calendar.getTime();
                if (consumeDayTimes.after(startOfDay) && consumeDayTimes.before(endOfDay)) {
                    firstNum = firstNum * DoubleNum;
                }
            }
        }
        if (storeCommercial) {
            if (i == 3) {
                CommercialDouble commercialDouble = commercialDoubleRepository.findByCommercialIdAndRemove(commercialId, 0);
                if (commercialDouble != null) {
                    Integer num = commercialDouble.getNum();
                    firstNum = firstNum * num;
                }
            }
        }
        return firstNum;
    }


    private int getFirstNumHLG(User user, PosOrder posOrder, String consumeDay, int firstNum, String commercialId) {
        String createTime = posOrder.getCreateTime();
        //判断消费日期是否是周三
        int i = 0;
        try {
            i = dayForWeek(consumeDay);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //当日时间
        String subTime = createTime.substring(0, 10);
        boolean timeDouble;
        boolean memberBirthDayDouble;
        boolean memberLevelDouble;
        boolean storeCommercial;

        //查询积分规则(先查缓存，没有缓存后查数据库)
        BoundHashOperations<String, String, Boolean> redisIntegralRule = redisTemplate.boundHashOps("integralRule");
        if (redisIntegralRule.size() > 0) {
            timeDouble = redisIntegralRule.get("timeDouble");
            memberBirthDayDouble = redisIntegralRule.get("memberBirthDayDouble");
            memberLevelDouble = redisIntegralRule.get("memberLevelDouble");
            storeCommercial = redisIntegralRule.get("storeCommercial");

        } else {
            IntegralRule integralRule = integralRuleService.findIntegralRule();
            timeDouble = integralRule.getTimeDouble();
            memberBirthDayDouble = integralRule.getMemberBirthDayDouble();
            memberLevelDouble = integralRule.getMemberLevelDouble();
            storeCommercial = integralRule.getStoreCommercial();
        }

        if (memberLevelDouble) {
            //会员等级翻倍
            String userId = user.getId();
            int multiply = userLevelService.findUserLevel(userId);
            firstNum = firstNum * multiply;
        }
        if (memberBirthDayDouble) {
            if (StringUtil.isNotEmpty(user.getBirthday())) {
                String substring = subTime.substring(5, 10);
                String userBirthday = user.getBirthday();
                if (StringUtils.isNotEmpty(userBirthday)) {
                    String birthDay = user.getBirthday().substring(5, 10);
                    if (birthDay.equals(substring)) {
                        //查询生日翻倍的倍数
                        String birthDayDouble = redisTemplate.opsForValue().get("birthDayDouble").toString();
                        int doubleNum = Integer.parseInt(birthDayDouble);
                        firstNum = firstNum * doubleNum;
                    }
                }


            }
        }
        if (timeDouble) {

            //查询时间段
            String integralTimeDouble = redisTemplate.opsForValue().get("integralTimeDouble").toString();
            if (StringUtil.isNotEmpty(integralTimeDouble)) {
                String[] times = integralTimeDouble.split(",");
                String startTime = times[0];
                String endTime = times[1];
                //翻倍系数
                String timeDoubleNum = times[2];
                int DoubleNum = Integer.parseInt(timeDoubleNum);

                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(startTime, DateUtils.DATE));
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(endTime, DateUtils.DATE));
                //查看小票消费日期
                Date consumeDayTime = DateUtils.parseStr2Date("yyyy-MM-dd", consumeDay);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(consumeDayTime);
                calendar.add(Calendar.HOUR, 1);
                Date consumeDayTimes = calendar.getTime();
                if (consumeDayTimes.after(startOfDay) && consumeDayTimes.before(endOfDay)) {
                    firstNum = firstNum * DoubleNum;
                }
            }
        }
        if (storeCommercial) {
            if (i == 3) {
                CommercialDouble commercialDouble = commercialDoubleRepository.findByCommercialIdAndRemove(commercialId, 0);
                if (commercialDouble != null) {
                    Integer num = commercialDouble.getNum();
                    firstNum = firstNum * num;
                }
            }
        }
        return firstNum;
    }


    private int integerNum(String money) {
        System.out.println("money...." + money);
        int i;
        boolean contains = money.contains(".");
        if (contains) {
            String substring = money.substring(0, (money.indexOf(".")));
            i = Integer.parseInt(substring);
        } else {
            i = Integer.parseInt(money);
        }
        return i;
    }

    /**
     * 创建申请
     *
     * @param requestBody
     */
    private void saveSelfHelpIntegral(SelfHelpRequestBody requestBody) {
        //创建申请
        SelfHelpIntegral selfHelpIntegral = new SelfHelpIntegral();
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(requestBody, selfHelpIntegral);
        selfHelpIntegral.setId(UUIDGenerator.getUUID());
        selfHelpIntegral.setRemove(0);
        selfHelpIntegral.setCreateTime(DateUtils.currentDate());
        selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.reviewing);
        selfHelpIntegralRepository.saveAndFlush(selfHelpIntegral);

        //绑定图片关系
        bandingImageShip(selfHelpIntegral.getId(), requestBody.getImageId());

    }

    /**
     * 绑定自助积分图片
     *
     * @param selfHelpIntegralId
     * @param imageId
     */
    private void bandingImageShip(String selfHelpIntegralId, String imageId) {
        ImageOutPut imageOutPut = new ImageOutPut();
        List<String> imageIds = new ArrayList<>();
        imageIds.add(imageId);
        imageOutPut.setForeignKeyId(selfHelpIntegralId);
        imageOutPut.setImageSource("self_help_integral");

        Map<String, Object> properties = new HashMap<>();
        properties.put("imageIds", imageIds);

        String exchange = "image.exchange";
        String routingKey = "image.selfHelpIntegral";

        rabbitSender.sendMessageToMQ(imageOutPut, properties, exchange, routingKey);
    }

    /**
     * 绑定自助积分图片
     *
     * @param
     * @param scratchId
     */
    private void addTimes(String userId, Long scratchId) {

        Map<String, Object> properties = new HashMap<>();
        properties.put("userId", userId);
        properties.put("scratchId", scratchId);

        String exchange = "scratch.exchange";
        String routingKey = "scratch.times";

        rabbitSender.sendMessageToMQ("刮刮卡加抽奖次数", properties, exchange, routingKey);
    }

    /**
     * 根据申请状态查询申请
     *
     * @param requestBody
     */
    public List<SelfHelpIntegralDTO> queryAllByStatus(SelfHelpRequestBody requestBody) throws SelfHelpIntegralException {
        Integer page = requestBody.getPage() == null ? 0 : requestBody.getPage();
        Integer size = requestBody.getSize() == null ? 100 : requestBody.getSize();
        String userId = requestBody.getUserId();

        String applicationStatus = requestBody.getApplicationStatus();

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);
        SelfHelpIntegral selfHelpIntegral = new SelfHelpIntegral();
        //设置floor的参数
        selfHelpIntegral.setRemove(0);
        selfHelpIntegral.setUserId(userId);
        if (SUCCESSPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.successpass);

        }
        if (FAILPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.failpass);

        }
        if (REVIEWING.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.reviewing);

        }
        Example<SelfHelpIntegral> example = Example.of(selfHelpIntegral);
        Page<SelfHelpIntegral> findAll = selfHelpIntegralRepository.findAll(example, pageable);
        List<SelfHelpIntegral> selfHelpIntegrals = findAll.getContent();
        List<String> storeIds = selfHelpIntegrals.stream().filter(distinctByKey(SelfHelpIntegral::getStoreId)).map(SelfHelpIntegral::getStoreId).collect(Collectors.toList());

        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(storeIds);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();

        List<SelfHelpIntegralDTO> selfHelpIntegralDTOS = new ArrayList<>();
        for (SelfHelpIntegral selfHelpIntegral1 : selfHelpIntegrals) {
            SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
            BeanUtils.copyProperties(selfHelpIntegral1, selfHelpIntegralDTO);
            selfHelpIntegralDTOS.add(selfHelpIntegralDTO);
        }

        for (SelfHelpIntegralDTO selfHelpIntegralDTO : selfHelpIntegralDTOS) {
            for (StoreDTO storeDTO : storeDTOS) {
                if (selfHelpIntegralDTO.getStoreId().equals(storeDTO.getId())) {
                    selfHelpIntegralDTO.setStoreName(storeDTO.getStoreName());
                    selfHelpIntegralDTO.setStoreCommercial(storeDTO.getStoreCommercial());
                }
            }
        }
        return selfHelpIntegralDTOS;
    }

    /**
     * 根据申请id查看申请详情
     *
     * @param selfHelpIntegralId
     */
    public SelfHelpIntegralDTO findSelfHelpIntegralDetails(String selfHelpIntegralId) {
        SelfHelpIntegral selfHelpIntegral = selfHelpIntegralRepository.findByIdAndRemove(selfHelpIntegralId, 0);
        SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(selfHelpIntegral, selfHelpIntegralDTO);
        selfHelpIntegralDTO.setSelfHelpIntegralId(selfHelpIntegral.getId());
        String storeId = selfHelpIntegral.getStoreId();
        ArrayList<String> storeIds = new ArrayList<>();
        storeIds.add(storeId);
        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(storeIds);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        StoreDTO storeDTO = storeDTOS.get(0);
        selfHelpIntegralDTO.setStoreName(storeDTO.getStoreName());
        return selfHelpIntegralDTO;
    }

    /**
     * 根据申请id查看申请详情(景枫版)
     *
     * @param selfHelpIntegralId
     */
    public SelfHelpIntegralDTO findSelfHelpIntegralDetailsJF(String selfHelpIntegralId) {
        SelfHelpIntegral selfHelpIntegral = selfHelpIntegralRepository.findByIdAndRemove(selfHelpIntegralId, 0);
        System.out.println(selfHelpIntegral);
        SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
        //通过映射关系来赋值 //TODO 断点看一下
        BeanUtils.copyProperties(selfHelpIntegral, selfHelpIntegralDTO);
        selfHelpIntegralDTO.setSelfHelpIntegralId(selfHelpIntegral.getId());
        return selfHelpIntegralDTO;
    }


    /**
     * 审核申请
     *
     * @param selfHelpIntegralId
     * @param applicationStatus
     * @param remarkApplication
     */
    public boolean reviewApplication(String selfHelpIntegralId, String applicationStatus, String remarkApplication, String storeId) throws UserException {
        SelfHelpIntegral selfHelpIntegral = selfHelpIntegralRepository.findByIdAndRemove(selfHelpIntegralId, 0);
        selfHelpIntegral.setStoreId(storeId);
        System.out.println(selfHelpIntegral);
        if (selfHelpIntegral == null) {
            return false;
        }
        if (selfHelpIntegral.getApplicationStatus().equals(SelfHelpIntegral.Application.successpass)) {
            return true;
        }
        String userId = selfHelpIntegral.getUserId();
        String consumeDay = selfHelpIntegral.getConsumeDay();

        User user = userService.getUserById(userId);

        List<String> list = new ArrayList<>();
        list.add(selfHelpIntegral.getStoreId());
        //根据商户id查询业态
        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(list);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        if (SUCCESSPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.successpass);

            systemReward(user, selfHelpIntegral, consumeDay, storeDTOS); //todo   可能有问题 没有返回判断
            //生成消费记录
            ConsumptionAmountRequestBody consumptionAmountRequestBody = new ConsumptionAmountRequestBody();//通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(selfHelpIntegral, consumptionAmountRequestBody);
            consumptionAmountRequestBody.setConsumeType("商场缴费");
            consumptionAmountService.createConsumptionAmount(consumptionAmountRequestBody);
            //根据金额和业态计算积分
            //发模板
            TemplateRequest templateRequest = new TemplateRequest();
            templateRequest.setDetail("满赠活动");
            templateRequest.setOpenId(user.getWxOpenid());
            templateRequest.setIntegral(selfHelpIntegral.getReceivePoint());
            templateRequest.setReason("小票自助核销");
            templateRequest.setCreateTime(selfHelpIntegral.getCreateTime());
            Integer integral = 0;
            if (selfHelpIntegral.getReceivePoint() != null) {
                integral = Integer.parseInt(selfHelpIntegral.getReceivePoint()) + integral;
            }
            Integer sumIntegral = user.getIntegral() + integral;
            templateRequest.setSumIntegral(Integer.toString(sumIntegral));
            templateRequest.setMoney(selfHelpIntegral.getMoney() + " 元");
            //填充商户信息
            IdDTO idDTO = new IdDTO();
            List<String> foreignKeyIds = new LinkedList<>();
            foreignKeyIds.add(selfHelpIntegral.getStoreId());
            idDTO.setForeignKeyIds(foreignKeyIds);
            StoreInfoDTO storeInfoDTO1 = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
            List<StoreDTO> stores = storeInfoDTO1.getStoreDTOS();
            System.out.println(stores.get(0).getStoreName());
            templateRequest.setShopName(stores.get(0).getStoreName());
            proxy.sendIntegralSumTemplate(templateRequest);

        }
        if (FAILPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.failpass);

        }

        selfHelpIntegral.setRemarkApplication(remarkApplication);
        selfHelpIntegralRepository.save(selfHelpIntegral);
        return true;
    }


    /**
     * 审核申请
     */
    public boolean reviewApplicationA(SelfHelpRequestBody requestBody) throws UserException {
        String selfHelpIntegralId = requestBody.getSelfHelpIntegralId();
        String money = requestBody.getMoney();
        String applicationStatus = requestBody.getApplicationStatus();
        String consumeDay = requestBody.getConsumeDay();
        String remarkApplication = requestBody.getRemarkApplication();
        String ticketNum = requestBody.getTicketNum();
        String auditChannel = requestBody.getAuditChannel();


        String storeId = requestBody.getStoreId();
        List<SelfHelpIntegral> selfHelpIntegral5= selfHelpIntegralRepository.checkSelfHelpIntegral(ticketNum, consumeDay, storeId);
        SelfHelpIntegral selfHelpIntegral1 =null;
        if(selfHelpIntegral5.size()>0){
            selfHelpIntegral1 = selfHelpIntegral5.get(0);
        }
        if (selfHelpIntegral1 != null && !(selfHelpIntegral1.getApplicationStatus()).equals(SelfHelpIntegral.Application.failpass)) {
            return false;
        }
        //根据用户手机号查询用户
        User user = userService.findUserByPhone(requestBody.getPhone());

        SelfHelpIntegral selfHelpIntegral = selfHelpIntegralRepository.findByIdAndRemove(selfHelpIntegralId, 0);

        if (selfHelpIntegral == null) {
            return false;
        }
        if (selfHelpIntegral.getApplicationStatus().equals(SelfHelpIntegral.Application.successpass)) {
            return true;
        }
        selfHelpIntegral.setStoreId(storeId);
        selfHelpIntegral.setMoney(money);
        selfHelpIntegral.setConsumeDay(consumeDay);
        selfHelpIntegral.setTicketNum(ticketNum);
        if (StringUtil.isNotEmpty(auditChannel)) {
            selfHelpIntegral.setAuditChannel(ARTIFICIAL);

        } else {
            selfHelpIntegral.setAuditChannel(CHECK);

        }
        List<String> list = new ArrayList<>();
        list.add(selfHelpIntegral.getStoreId());
        //根据商户id查询业态
        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(list);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        if (SUCCESSPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.successpass);

            systemReward(user, selfHelpIntegral, consumeDay, storeDTOS); //todo   可能有问题 没有返回判断
            //生成消费记录
            ConsumptionAmountRequestBody consumptionAmountRequestBody = new ConsumptionAmountRequestBody();//通过映射关系来赋值 //TODO 断点看一下
            BeanUtils.copyProperties(selfHelpIntegral, consumptionAmountRequestBody);
            consumptionAmountRequestBody.setConsumeType("商场缴费");
            consumptionAmountService.createConsumptionAmount(consumptionAmountRequestBody);
            //根据金额和业态计算积分

            //发送任务队列，完成小票任务

            Map<String, Object> properties = new HashMap<>();
            properties.put("userId", selfHelpIntegral.getUserId());
            properties.put("taskType", "selfHelpIntegral");

            //将计算结果放到MQ队列去补充明细的余额
            String msg = "补全积分明细余额";
            String exchange = "task.exchange";
            String routingKey = "task.sign";
            rabbitSender.sendMessageToMQ(msg, properties, exchange, routingKey);

            //发模板
            TemplateRequest templateRequest = new TemplateRequest();
            templateRequest.setDetail("满赠活动");
            templateRequest.setOpenId(user.getWxOpenid());
            templateRequest.setIntegral(selfHelpIntegral.getReceivePoint());
            templateRequest.setReason("小票自助核销");
            templateRequest.setCreateTime(selfHelpIntegral.getCreateTime());
            Integer integral = 0;
            if (selfHelpIntegral.getReceivePoint() != null) {
                integral = Integer.parseInt(selfHelpIntegral.getReceivePoint()) + integral;
            }
            Integer sumIntegral = user.getIntegral() + integral;
            templateRequest.setSumIntegral(Integer.toString(sumIntegral));
            templateRequest.setMoney(selfHelpIntegral.getMoney() + " 元");
            //填充商户信息
            IdDTO idDTO = new IdDTO();
            List<String> foreignKeyIds = new LinkedList<>();
            foreignKeyIds.add(selfHelpIntegral.getStoreId());
            idDTO.setForeignKeyIds(foreignKeyIds);
            StoreInfoDTO storeInfoDTO1 = restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
            List<StoreDTO> stores = storeInfoDTO1.getStoreDTOS();
            System.out.println(stores.get(0).getStoreName());
            templateRequest.setShopName(stores.get(0).getStoreName());
            proxy.sendIntegralSumTemplate(templateRequest);

        }
        if (FAILPASS.equals(applicationStatus)) {
            selfHelpIntegral.setApplicationStatus(SelfHelpIntegral.Application.failpass);

        }

        selfHelpIntegral.setRemarkApplication(remarkApplication);
        selfHelpIntegralRepository.save(selfHelpIntegral);
        return true;
    }


    //自助积分
    private void sountIntegral(String integralPoint, SelfHelpIntegral selfHelpIntegral, String userId) {
        IntegralOutPut integralOutPut = new IntegralOutPut();
        integralOutPut.setConsumeType("selfHelp");
        integralOutPut.setForeignKeyId(selfHelpIntegral.getStoreId());
        integralOutPut.setIntegralPoint(integralPoint);
        integralOutPut.setMoney(selfHelpIntegral.getMoney());
        integralOutPut.setOrderNum(selfHelpIntegral.getId());
        integralOutPut.setUserId(userId);
        integralOutPut.setSource("自助积分");
        integralOutPut.setTradeAction(0);
        integralOutPut.setTradingContent("自助小票兑换积分");

        String exchange = "integral.exchange";
        String routingKey = "integral.selfHelp";
        rabbitSender.sendMessageToMQ(integralOutPut, null, exchange, routingKey);
    }

    /**
     * 删除申请
     *
     * @param selfHelpIntegralId
     * @return
     */
    public boolean removeApplication(String selfHelpIntegralId) {
        SelfHelpIntegral selfHelpIntegral = selfHelpIntegralRepository.findByIdAndRemove(selfHelpIntegralId, 0);
        if (selfHelpIntegral == null) {
            return false;
        }
        selfHelpIntegral.setRemove(1);
        selfHelpIntegralRepository.save(selfHelpIntegral);
        return true;
    }

    /**
     * 查找小票集合
     *
     * @return
     */
    public PageDTO<SelfHelpIntegralDTO> list(SelfHelpRequestBody requestBody, String applicationStatus) {
        Integer page = null == requestBody.getPage() ? 0 : requestBody.getPage();
        Integer size = null == requestBody.getSize() ? 10 : requestBody.getSize();
        String to = requestBody.getToDate();
        String from = requestBody.getFromDate();
        String keyword = requestBody.getKeyword();
        String ticketNum = requestBody.getTicketNum();
        String phone = requestBody.getPhone();
        String auditChannel = requestBody.getAuditChannel();
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);

        Page<SelfHelpIntegral> paged = selfHelpIntegralRepository.findAll((Specification<SelfHelpIntegral>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (StringUtil.isNotEmpty(keyword)) {
                IdDTO idDTO1 = new IdDTO();
                idDTO1.setKeyWord(keyword);
                StoreInfoDTO storeInfoDTO1 = restTemplate.postForObject("http://QUANQUAN-STORE/store/page_find_store", idDTO1, StoreInfoDTO.class);
                List<StoreDTO> stores = storeInfoDTO1.getStoreDTOS();
                if (stores.size() > 0) {
                    StoreDTO storeDTO = stores.get(0);
                    predicates.add(cb.equal(root.get("storeId").as(String.class), storeDTO.getId()));
                } else if (stores.size() <= 0) {
                    List<User> users = userService.findListByKeyword(keyword);
                    if (users.size() > 0) {
                        User user = users.get(0);
                        predicates.add(cb.equal(root.get("userId").as(String.class), user.getId()));
                    } else {
                        predicates.add(cb.like(root.get("phone").as(String.class), "%" + keyword + "%"));
                    }

                }

            }
            if (StringUtil.isNotEmpty(auditChannel)) {
                predicates.add(cb.equal(root.get("auditChannel").as(String.class), auditChannel));
            }

            if (StringUtil.isNotEmpty(from)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(from, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("consumeDay").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(to)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(to, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("consumeDay").as(Date.class), endOfDay));
            }


            if (StringUtil.isNotEmpty(ticketNum)) {
                predicates.add(cb.like(root.get("ticketNum").as(String.class), "%" + ticketNum + "%"));
            }


            predicates.add(cb.equal(root.get("remove").as(Integer.class), 0));
            if (applicationStatus.equals(SUCCESSPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.successpass));
            }
            if (applicationStatus.equals(REVIEWING)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.reviewing));
            }
            if (applicationStatus.equals(FAILPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.failpass));
            }

            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
        List<SelfHelpIntegralDTO> selfHelpIntegralDTOS = new ArrayList<>();
        List<SelfHelpIntegral> selfHelpIntegrals = paged.getContent();
        List<String> storeIds = selfHelpIntegrals.stream().filter(distinctByKey(SelfHelpIntegral::getStoreId)).map(SelfHelpIntegral::getStoreId).collect(Collectors.toList());

        StoreInfoDTO storeInfoDTO = getStoreInfoDTO(storeIds);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        for (SelfHelpIntegral selfHelpIntegral1 : selfHelpIntegrals) {
            SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
            BeanUtils.copyProperties(selfHelpIntegral1, selfHelpIntegralDTO);
            selfHelpIntegralDTO.setSelfHelpIntegralId(selfHelpIntegral1.getId());
            selfHelpIntegralDTOS.add(selfHelpIntegralDTO);
        }

        for (SelfHelpIntegralDTO selfHelpIntegralDTO : selfHelpIntegralDTOS) {
            for (StoreDTO storeDTO : storeDTOS) {
                if (selfHelpIntegralDTO.getStoreId().equals(storeDTO.getId())) {
                    selfHelpIntegralDTO.setStoreName(storeDTO.getStoreName());
                    selfHelpIntegralDTO.setStoreCommercial(storeDTO.getStoreCommercial());
                }
            }
        }

        List<String> phones = selfHelpIntegrals.stream().filter(distinctByKey(SelfHelpIntegral::getPhone)).map(SelfHelpIntegral::getPhone).collect(Collectors.toList());

        List<User> users = userService.findUsersByPhone(phones);
        //将积分的关于用户的信息补上
        for (User user : users) {
            for (SelfHelpIntegralDTO selfHelpIntegralDTO : selfHelpIntegralDTOS) {
                if ((user.getPhone()).equals(selfHelpIntegralDTO.getPhone())) {
                    selfHelpIntegralDTO.setPhone(user.getPhone());
                    selfHelpIntegralDTO.setMemberName(user.getMemberName());
                }
            }
        }

        PageDTO<SelfHelpIntegralDTO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(paged.getTotalElements());
        pageDTO.setList(selfHelpIntegralDTOS);
        pageDTO.setTotalPage(paged.getTotalPages());
        pageDTO.setPage(page);
        pageDTO.setPageSize(size);
        pageDTO.setFromDate(from);
        pageDTO.setTicketNum(ticketNum);
        pageDTO.setPhone(phone);
        pageDTO.setToDate(to);
        pageDTO.setKeyword(keyword);
        return pageDTO;
    }

    /**
     * 拿取商铺的信息
     *
     * @param storeIds
     * @return
     */
    private StoreInfoDTO getStoreInfoDTOs(List<String> storeIds) {
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(storeIds);

        return restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_store_num_list", idDTO, StoreInfoDTO.class);
    }



    /**
     * 拿取商铺的信息
     *
     * @param storeIds
     * @return
     */
    private StoreInfoDTO getStoreInfoDTO(List<String> storeIds) {
        IdDTO idDTO = new IdDTO();
        idDTO.setForeignKeyIds(storeIds);

        return restTemplate.postForObject("http://QUANQUAN-STORE/store/query_by_id_list", idDTO, StoreInfoDTO.class);
    }
    /**
     * 拿取商铺业态的信息
     *
     * @param commercialId
     * @return
     */
    private CommercialInfoDTO getCommercialInfoDTO(String commercialId) {
        IdDTO idDTO = new IdDTO();
        idDTO.setCommercialId(commercialId);
        return restTemplate.postForObject("http://QUANQUAN-STORE/commercial/get_commercial_info", idDTO, CommercialInfoDTO.class);
    }


    private static <T> java.util.function.Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    public PageDTO<SelfHelpIntegralDTO> queryReviewingRecord(SelfHelpRequestBody requestBody) {

        Integer page = requestBody.getPage() == null ? 0 : requestBody.getPage();
        Integer size = requestBody.getSize() == null ? 100 : requestBody.getSize();

        String userId = requestBody.getUserId();
        String keyword = requestBody.getKeyword();
        System.out.println("keyword.........." + keyword);
        String fromDate = requestBody.getFromDate();
        String toDate = requestBody.getToDate();
        String applicationStatus = requestBody.getApplicationStatus();
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);
        Page<SelfHelpIntegral> paged = selfHelpIntegralRepository.findAll((Specification<SelfHelpIntegral>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (StringUtil.isNotEmpty(keyword)) {
                List<User> users = userService.findListByKeyword(keyword);
                if (users.size() > 0) {
                    User user = users.get(0);
                    predicates.add(cb.equal(root.get("userId").as(String.class), user.getId()));
                    Predicate p1 = cb.equal(root.get("userId").as(String.class), user.getId());
                    Predicate p2 = cb.or(cb.like(root.get("phone").as(String.class), "%" + keyword + "%"), p1);

                    predicates.add(p2);
                }

            }


            if (StringUtil.isNotEmpty(fromDate)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(fromDate, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(toDate)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(toDate, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }


            predicates.add(cb.equal(root.get("remove").as(Integer.class), 0));

            if (StringUtil.isNotEmpty(userId)) {
                predicates.add(cb.equal(root.get("userId").as(String.class), userId));

            }

            if (applicationStatus.equals(SUCCESSPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.successpass));
            }
            if (applicationStatus.equals(REVIEWING)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.reviewing));
            }
            if (applicationStatus.equals(FAILPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.failpass));
            }

            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);

        List<SelfHelpIntegralDTO> selfHelpIntegralDTOS = new ArrayList<>();
        List<SelfHelpIntegral> selfHelpIntegrals = paged.getContent();
        for (SelfHelpIntegral selfHelpIntegral1 : selfHelpIntegrals) {
            SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
            BeanUtils.copyProperties(selfHelpIntegral1, selfHelpIntegralDTO);
            selfHelpIntegralDTO.setSelfHelpIntegralId(selfHelpIntegral1.getId());
            selfHelpIntegralDTOS.add(selfHelpIntegralDTO);
        }

        PageDTO<SelfHelpIntegralDTO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(paged.getTotalElements());
        pageDTO.setList(selfHelpIntegralDTOS);
        pageDTO.setTotalPage(paged.getTotalPages());
        pageDTO.setPage(page);
        pageDTO.setKeyword(keyword);
        pageDTO.setPageSize(size);
        pageDTO.setFromDate(fromDate);
        pageDTO.setToDate(toDate);


        return pageDTO;
    }


    /**
     * 查找小票集合(景枫特供)
     *
     * @return
     */
    public PageDTO<SelfHelpIntegralDTO> listJF(SelfHelpRequestBody requestBody, String applicationStatus) {
        Integer page = null == requestBody.getPage() ? 0 : requestBody.getPage();
        Integer size = null == requestBody.getSize() ? 10 : requestBody.getSize();
        String to = requestBody.getToDate();
        String from = requestBody.getFromDate();

        String keyword = requestBody.getKeyword();
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page, size, sort);
        String auditChannel = requestBody.getAuditChannel();

        Page<SelfHelpIntegral> paged = selfHelpIntegralRepository.findAll((Specification<SelfHelpIntegral>) (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (StringUtil.isNotEmpty(keyword)) {
                List<User> users = userService.findListByKeyword(keyword);
                if (users.size() > 0) {
                    User user = users.get(0);
                    predicates.add(cb.equal(root.get("userId").as(String.class), user.getId()));
                } else {
                    predicates.add(cb.like(root.get("phone").as(String.class), "%" + keyword + "%"));
                }


            }

            if (StringUtil.isNotEmpty(from)) {
                Date startOfDay = DateUtils.getStartOfDay(DateUtils.strToDate(from, DateUtils.DATE));

                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(Date.class), startOfDay));
            }
            if (StringUtil.isNotEmpty(to)) {
                Date endOfDay = DateUtils.getEndOfDay(DateUtils.strToDate(to, DateUtils.DATE));
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(Date.class), endOfDay));
            }


            predicates.add(cb.equal(root.get("remove").as(Integer.class), 0));

            if (StringUtil.isNotEmpty(auditChannel)) {
                predicates.add(cb.equal(root.get("auditChannel").as(String.class), auditChannel));
            }

            if (applicationStatus.equals(SUCCESSPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.successpass));
            }
            if (applicationStatus.equals(REVIEWING)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.reviewing));
            }
            if (applicationStatus.equals(FAILPASS)) {
                predicates.add(cb.equal(root.get("applicationStatus").as(SelfHelpIntegral.Application.class), SelfHelpIntegral.Application.failpass));
            }

            return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
        }, pageable);
        List<SelfHelpIntegralDTO> selfHelpIntegralDTOS = new ArrayList<>();
        List<SelfHelpIntegral> selfHelpIntegrals = paged.getContent();

        List<String> phones = selfHelpIntegrals.stream().filter(distinctByKey(SelfHelpIntegral::getPhone)).map(SelfHelpIntegral::getPhone).collect(Collectors.toList());

        List<User> users = userService.findUsersByPhone(phones);
        //将积分的关于用户的信息补上

        for (SelfHelpIntegral selfHelpIntegral1 : selfHelpIntegrals) {
            SelfHelpIntegralDTO selfHelpIntegralDTO = new SelfHelpIntegralDTO();
            BeanUtils.copyProperties(selfHelpIntegral1, selfHelpIntegralDTO);
            selfHelpIntegralDTO.setSelfHelpIntegralId(selfHelpIntegral1.getId());
            selfHelpIntegralDTOS.add(selfHelpIntegralDTO);
        }

        for (User user : users) {
            for (SelfHelpIntegralDTO selfHelpIntegralDTO : selfHelpIntegralDTOS) {
                if ((user.getPhone()).equals(selfHelpIntegralDTO.getPhone())) {
                    selfHelpIntegralDTO.setPhone(user.getPhone());
                    String memberName = user.getMemberName();
                    selfHelpIntegralDTO.setMemberName(memberName);
                }
            }
        }
        PageDTO<SelfHelpIntegralDTO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(paged.getTotalElements());
        pageDTO.setList(selfHelpIntegralDTOS);
        pageDTO.setTotalPage(paged.getTotalPages());
        pageDTO.setPage(page);
        pageDTO.setPageSize(size);
        pageDTO.setFromDate(from);
        pageDTO.setToDate(to);
        return pageDTO;
    }

    public Map<String ,String> createSelfHelpApplicationAndAutoAutomatic(PosOrder posOrder)  {
        Map<String, String> map = new HashMap<>();
        //根据用户手机号查询用户
        User user = userService.findUserByPhone(posOrder.getPhone());

        if (user == null) {
            map.put("msg","用户信息错误");
            return map;
        }
        Integer freeze = user.getFreeze();
        if (freeze != 0) {
            map.put("msg","该用户已被冻结");

            return map;
        }
        String userId = user.getId();
        String consumeDay = posOrder.getConsumeDay();
        //参与营销活动结算积分
        List<String> list = new ArrayList<>();
        list.add(posOrder.getStoreId());
        //根据商户id查询业态
        StoreInfoDTO storeInfoDTO = getStoreInfoDTOs(list);
        List<StoreDTO> storeDTOS = storeInfoDTO.getStoreDTOS();
        StoreDTO storeDTO;
        if (storeDTOS.size() > 0) {
             storeDTO = storeDTOS.get(0);
            String money = posOrder.getMoney();
            //根据key值查询业态信息
            String commercialId = storeDTO.getCommercialId();
            int integralProportion = 1;
            try {
                String result = redisTemplate.opsForValue().get(COMMERCIAL + commercialId).toString();
                if (StringUtil.isNotEmpty(result)) {
                    integralProportion = Integer.parseInt(result);
                }
            } catch (Exception e) {
                //http 根据业态id查询业态信息
                CommercialInfoDTO commercialInfoDTO = getCommercialInfoDTO(commercialId);
                if (commercialInfoDTO != null) {
                    integralProportion = commercialInfoDTO.getPercent();
                }
            }

            //金额取整
            int i = integerNum(money);
            //会员翻倍，业态兑换比例，生日翻倍，时间段翻倍
            int firstNum = 0;
            if (i != 0) {
                //算出积分(业态兑换比例)
                firstNum = i / integralProportion;
            }
            //积分翻倍规则(会员等级翻倍 ，会员生日翻倍，时间段翻倍)
            firstNum = getFirstNumHLG(user, posOrder, consumeDay, firstNum, commercialId);

            //生日翻倍
            //时间段翻倍

            String integralPoint = String.valueOf(firstNum);

            IntegralOutPut integralOutPut = new IntegralOutPut();
            integralOutPut.setConsumeType("selfHelp");
            integralOutPut.setForeignKeyId(posOrder.getStoreId());
            integralOutPut.setIntegralPoint(integralPoint);
            integralOutPut.setMoney(posOrder.getMoney());
            integralOutPut.setOrderNum(posOrder.getId());
            integralOutPut.setUserId(userId);
            integralOutPut.setSource("pos参与营销活动积分");
            integralOutPut.setTradeAction(0);
            integralOutPut.setTradingContent("pos参与营销活动积分");

            String exchange = "integral.exchange";
            String routingKey = "integral.selfHelp";
            rabbitSender.sendMessageToMQ(integralOutPut, null, exchange, routingKey);

            //生成消费记录
            ConsumptionAmountRequestBody consumptionAmountRequestBody = new ConsumptionAmountRequestBody();//通过映射关系来赋值 //TODO 断点看一下
            consumptionAmountRequestBody.setTicketNum(posOrder.getTicketNum());
            consumptionAmountRequestBody.setConsumeDay(posOrder.getConsumeDay());
            consumptionAmountRequestBody.setMoney(posOrder.getMoney());
            consumptionAmountRequestBody.setStoreId(storeDTO.getId());
            consumptionAmountRequestBody.setPhone(user.getPhone());
            consumptionAmountRequestBody.setUserId(userId);
            //同步消费数据
            consumptionAmountRequestBody.setConsumeType("pos消费");
            consumptionAmountService.createConsumptionAmount(consumptionAmountRequestBody);




            posOrder.setReceivePoint(integralPoint);
            posOrderRepository.save(posOrder);
            Integer integer = Integer.valueOf(user.getIntegral());
            Integer s= integer+ firstNum;
            System.out.println("s"+s);
            map.put("integral",integralPoint);
            map.put("totalIntegral", s.toString());
            return map;

        }
        map.put("msg","参与失败");
        return map;
    }
}
